package com.aplink.generic.xmlparser;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.text.TextUtils;

import com.aplink.generic.dictionary.GenericDictionary;
import com.aplink.generic.pojo.AutoSync;
import com.aplink.generic.pojo.CloudNotification;
import com.aplink.generic.pojo.MasterConfig;
import com.aplink.generic.pojo.TableInit;
import com.aplink.generic.pojo.TableSyncData;

public class MasterConfigParser {
    public static final String AUTHORITIES = "Authorities";
    public static final String AUTO_SYNC = "AutoSync";
    public static final String AUTO_SYNC_INTERVAL = "AutoSyncInterval";
    public static final String CHANGE_PASSWORD = "ChangePassword";
    public static final String CONTENT_TITLE = "ContentTitle";
    public static final String DATABASE_NAME = "DatabaseName";
    public static final String DATABASE_VERSION = "DatabaseVersion";
    public static final String DEMO_DATA = "DemoData";
    public static final String ENABLE = "enable";
    public static final String FORGOT_PASSWORD = "ForgotPassword";
    public static final String ICON = "Icon";
    public static final String INIT_DATA = "InitData";
    public static String IS_CLEAR_ALL = "isClearAll";
    public static final String IS_DEMO = "isDemo";
    public static String IS_DOWNLOAD_ONLY = "isDownloadOnly";
    public static final String IS_HAVE_PHOTO = "isHavePhoto";
    public static final String LOGIN_SCREEN = "FirstScreen";
    public static String MAIN_MENU = "MainMenu";
    public static final String MASTER_CONFIG = "MasterConfig";
    public static final String MESSAGE = "Message";
    public static final String MESSAGE_TAG = "MessageTag";
    public static final String NAME = "MasterConfig";
    public static final String NOTIFICATION = "Notification";
    public static final String OFFLINE_MODE = "OfflineMode";
    public static final String SENDER_ID = "SenderID";
    public static final String SOUND = "Sound";
    public static final String SYNC_TABLE_LIST = "SyncTableList";
    public static final String TABLE_DOWNLOAD = "TableDownload";
    public static final String TABLE_INIT = "TableInit";
    public static final String TABLE_LIST = "InitTableList";
    public static final String TABLE_STRUCTURE = "TableStructure";
    public static final String TRY_TIME = "TryTimes";
    public static final String WEBSERVICE = "WebService";
    public static final String WEBSERVICE_DOMAIN = "WebserviceDomain";

    public static final String WEBSERVICE_FUNCTION = "WebserviceFunction";

    private static AutoSync autoSyncParser(Node node) {
        final AutoSync autoSync = new AutoSync();
        Element element = (Element) node;

        NodeList nodeList = element
                .getElementsByTagName(MasterConfigParser.AUTO_SYNC_INTERVAL);
        String value = null;
        if (nodeList.getLength() == 1) {
            value = XMLPaserUtil.getNodeValue(nodeList.item(0));
            if (!TextUtils.isEmpty(value)) {
                autoSync.setInterval(Integer.parseInt(value));
            }
        }
        nodeList = element.getElementsByTagName(MasterConfigParser.AUTHORITIES);
        if (nodeList.getLength() == 1) {
            value = XMLPaserUtil.getNodeValue(nodeList.item(0));
            if (!TextUtils.isEmpty(value)) {
                autoSync.setAuthorities(value);
            }
        }
        nodeList = element
                .getElementsByTagName(MasterConfigParser.NOTIFICATION);
        if (nodeList.getLength() == 1) {
            node = nodeList.item(0);
            element = (Element) node;
            nodeList = element.getElementsByTagName(MasterConfigParser.ICON);
            if (nodeList.getLength() == 1) {
                value = XMLPaserUtil.getNodeValue(nodeList.item(0));
                if (!TextUtils.isEmpty(value)) {
                    autoSync.setIcon(value);
                }
            }

            nodeList = element.getElementsByTagName(MasterConfigParser.MESSAGE);
            if (nodeList.getLength() == 1) {
                value = XMLPaserUtil.getNodeValue(nodeList.item(0));
                if (!TextUtils.isEmpty(value)) {
                    autoSync.setMessage(value);
                }
            }

            nodeList = element
                    .getElementsByTagName(MasterConfigParser.CONTENT_TITLE);
            if (nodeList.getLength() == 1) {
                value = XMLPaserUtil.getNodeValue(nodeList.item(0));
                if (!TextUtils.isEmpty(value)) {
                    autoSync.setContentTitle(value);
                }
            }
        }

        return autoSync;
    }

    private static MasterConfig parse(final Document doc) {
        final MasterConfig masterConfig = new MasterConfig();
        final NodeList nList = doc
                .getElementsByTagName(MasterConfigParser.NAME);
        if (nList.getLength() == 0) {
            return new MasterConfig();
        }
        final Node nNode = nList.item(0);
        if (nNode.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) nNode;
            NodeList nodeList = null;
            // parse database name
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.DATABASE_NAME);
            Node node = null;
            String nodeValue = null;
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                nodeValue = XMLPaserUtil.getNodeValue(node);
                masterConfig.setDatabaseName(nodeValue);
            }

            // parse database version
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.DATABASE_VERSION);
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                nodeValue = XMLPaserUtil.getNodeValue(node);
                if (TextUtils.isEmpty(nodeValue)) {
                    masterConfig.setDatabaseVersion(1);
                } else {
                    masterConfig
                            .setDatabaseVersion(Integer.parseInt(nodeValue));
                }
            }

            // parse TableStructure
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.TABLE_STRUCTURE);
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                nodeValue = XMLPaserUtil.getNodeValue(node);
                if (!TextUtils.isEmpty(nodeValue)) {
                    masterConfig.setTableStructure(nodeValue);
                }
            }

            // parse Main Menu
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.MAIN_MENU);
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                nodeValue = XMLPaserUtil.getNodeValue(node);
                if (!TextUtils.isEmpty(nodeValue)) {
                    masterConfig.setMainMenu(nodeValue);
                }
            }

            nodeList = element
                    .getElementsByTagName(MasterConfigParser.AUTO_SYNC);
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                if (node.hasAttributes()) {
                    final AutoSync autoSync = MasterConfigParser
                            .autoSyncParser(node);
                    final String value = XMLPaserUtil.getAttrValue(node,
                            MasterConfigParser.ENABLE);
                    if (!TextUtils.isEmpty(value)
                            && value.equalsIgnoreCase("Y")) {
                        autoSync.setEnable(true);
                    }
                    masterConfig.setAutoSync(autoSync);
                }
            }

            // parse DemoData
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.DEMO_DATA);
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                nodeValue = XMLPaserUtil.getNodeValue(node);
                if (!TextUtils.isEmpty(nodeValue)) {
                    masterConfig.setDemoData(nodeValue);
                }

                if (node.hasAttributes()) {
                    final String demoData = XMLPaserUtil.getAttrValue(node,
                            MasterConfigParser.IS_DEMO);
                    if ((demoData != null) && demoData.equalsIgnoreCase("Y")) {
                        masterConfig.setDemo(true);
                    }
                }

            }

            // Parse OfflineMode
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.OFFLINE_MODE);
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                nodeValue = XMLPaserUtil.getNodeValue(node);
                if (!TextUtils.isEmpty(nodeValue)) {
                    if (nodeValue.equalsIgnoreCase("ON")) {
                        masterConfig.setHasOfflineMode(true);
                    }
                }
            }
            // Parse LoginScreen
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.LOGIN_SCREEN);
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                nodeValue = XMLPaserUtil.getNodeValue(node);
                if (!TextUtils.isEmpty(nodeValue)) {
                    masterConfig.setLoginClass(nodeValue);
                }
            }
            // Parse OfflineMode
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.TRY_TIME);
            if (nodeList.getLength() == 1) {
                node = nodeList.item(0);
                nodeValue = XMLPaserUtil.getNodeValue(node);
                if (!TextUtils.isEmpty(nodeValue)) {
                    final int tryTime = Integer.parseInt(nodeValue);
                    masterConfig.setTryTime(tryTime);
                }
            }
            nodeList = element
                    .getElementsByTagName(MasterConfigParser.NOTIFICATION);
            for (int i = 0; i < nodeList.getLength(); i++) {
                node = nodeList.item(i);
                if (node.getParentNode().getNodeName()
                        .equalsIgnoreCase(MasterConfigParser.MASTER_CONFIG)) {
                    masterConfig.setCloudNotification(MasterConfigParser
                            .parseCloudNotification(node));
                }
            }

            // Parse OfflineMode
            final NodeList webservice = element
                    .getElementsByTagName(MasterConfigParser.WEBSERVICE);
            if (webservice.getLength() > 0) {
                node = element.getElementsByTagName(
                        MasterConfigParser.WEBSERVICE).item(0);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    element = (Element) node;

                    // Parse webService domain
                    nodeList = element
                            .getElementsByTagName(MasterConfigParser.WEBSERVICE_DOMAIN);
                    if (nodeList.getLength() == 1) {
                        node = nodeList.item(0);
                        nodeValue = XMLPaserUtil.getNodeValue(node);
                        masterConfig.getWebserviceConfig().setWebserviceDomain(
                                nodeValue);
                    }

                    // Parse ChangePassword
                    nodeList = element
                            .getElementsByTagName(MasterConfigParser.CHANGE_PASSWORD);
                    if (nodeList.getLength() == 1) {
                        node = element.getElementsByTagName(
                                MasterConfigParser.CHANGE_PASSWORD).item(0);
                        nodeValue = XMLPaserUtil.getNodeValue(node);
                        masterConfig.getWebserviceConfig().setChangePassword(
                                nodeValue);
                    }

                    // Parse ChangePassword
                    nodeList = element
                            .getElementsByTagName(MasterConfigParser.FORGOT_PASSWORD);
                    if (nodeList.getLength() == 1) {
                        node = element.getElementsByTagName(
                                MasterConfigParser.FORGOT_PASSWORD).item(0);
                        nodeValue = XMLPaserUtil.getNodeValue(node);
                        masterConfig.getWebserviceConfig().setForgotPassword(
                                nodeValue);
                    }
                    // Parse InitData
                    nodeList = element
                            .getElementsByTagName(MasterConfigParser.INIT_DATA);
                    if (nodeList.getLength() == 1) {
                        node = element.getElementsByTagName(
                                MasterConfigParser.INIT_DATA).item(0);
                        nodeValue = XMLPaserUtil.getNodeValue(node);
                        masterConfig.getWebserviceConfig().setInitData(
                                nodeValue);
                    }
                    // Parse InitTableList
                    nodeList = element
                            .getElementsByTagName(MasterConfigParser.TABLE_LIST);
                    if (nodeList.getLength() == 1) {
                        node = element.getElementsByTagName(
                                MasterConfigParser.TABLE_LIST).item(0);
                        final Element tableListElement = (Element) node;
                        nodeList = tableListElement
                                .getElementsByTagName(MasterConfigParser.TABLE_INIT);
                        final GenericDictionary<String, TableInit> tableInits = MasterConfigParser
                                .parseTableInit(nodeList);
                        masterConfig.getWebserviceConfig().setTableInits(
                                tableInits);
                    }

                    // Parse SyncTableList
                    nodeList = element
                            .getElementsByTagName(MasterConfigParser.SYNC_TABLE_LIST);
                    if (nodeList.getLength() == 1) {
                        node = element.getElementsByTagName(
                                MasterConfigParser.SYNC_TABLE_LIST).item(0);
                        final Element syncTableList = (Element) node;
                        nodeList = syncTableList
                                .getElementsByTagName(MasterConfigParser.TABLE_DOWNLOAD);
                        final GenericDictionary<String, TableSyncData> tableDownloads = MasterConfigParser
                                .parseTableDownload(nodeList);
                        masterConfig.getWebserviceConfig().setTableDownloads(
                                tableDownloads);
                    }

                }
            }
        }
        return masterConfig;
    }

    private static CloudNotification parseCloudNotification(final Node node) {
        final CloudNotification cloudNotification = new CloudNotification();
        final Element element = (Element) node;
        NodeList nodeList = element
                .getElementsByTagName(MasterConfigParser.SENDER_ID);
        String value = null;
        if (nodeList.getLength() == 1) {
            value = XMLPaserUtil.getNodeValue(nodeList.item(0));
            if (!TextUtils.isEmpty(value)) {
                cloudNotification.setSender(value);
            }
        }

        nodeList = element.getElementsByTagName(MasterConfigParser.ICON);
        if (nodeList.getLength() == 1) {
            value = XMLPaserUtil.getNodeValue(nodeList.item(0));
            if (!TextUtils.isEmpty(value)) {
                cloudNotification.setIcon(value);
            }
        }
        nodeList = element
                .getElementsByTagName(MasterConfigParser.CONTENT_TITLE);
        if (nodeList.getLength() == 1) {
            value = XMLPaserUtil.getNodeValue(nodeList.item(0));
            if (!TextUtils.isEmpty(value)) {
                cloudNotification.setContentTitle(value);
            }
        }
        nodeList = element.getElementsByTagName(MasterConfigParser.SOUND);
        if (nodeList.getLength() == 1) {
            value = XMLPaserUtil.getNodeValue(nodeList.item(0));
            if (!TextUtils.isEmpty(value)) {
                cloudNotification.setSound(value);
            }
        }

        nodeList = element.getElementsByTagName(MasterConfigParser.MESSAGE_TAG);
        if (nodeList.getLength() == 1) {
            value = XMLPaserUtil.getNodeValue(nodeList.item(0));
            if (!TextUtils.isEmpty(value)) {
                cloudNotification.setMessageTag(value);
            }
        }
        return cloudNotification;
    }

    public static MasterConfig parserIntoControls(final int xmlFileId) {
        try {
            final Document doc = XMLPaserUtil.openDocumentFrom(xmlFileId);
            return MasterConfigParser.parse(doc);
        } catch (final NotFoundException e) {
            e.printStackTrace();
        } catch (final ParserConfigurationException e) {
            e.printStackTrace();
        } catch (final SAXException e) {
            e.printStackTrace();
        } catch (final IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static MasterConfig parserIntoControls(final int xmlFileId,
            final Context context) {
        try {
            final Document doc = XMLPaserUtil.openDocumentFrom(xmlFileId,
                    context);
            return MasterConfigParser.parse(doc);
        } catch (final NotFoundException e) {
            e.printStackTrace();
        } catch (final ParserConfigurationException e) {
            e.printStackTrace();
        } catch (final SAXException e) {
            e.printStackTrace();
        } catch (final IOException e) {
            e.printStackTrace();
        }
        return null;

    }

    private static GenericDictionary<String, TableSyncData> parseTableDownload(
            final NodeList nodeList) {
        if (nodeList.getLength() == 0) {
            return new GenericDictionary<String, TableSyncData>();
        }
        final GenericDictionary<String, TableSyncData> tableDownloads = new GenericDictionary<String, TableSyncData>();
        for (int i = 0; i < nodeList.getLength(); i++) {
            final Node node = nodeList.item(i);
            String value = XMLPaserUtil.getNodeValue(node);
            final TableSyncData tableDownload = new TableSyncData();
            tableDownload.setTableName(value);

            if (node.hasAttributes()) {
                value = XMLPaserUtil.getAttrValue(node,
                        MasterConfigParser.WEBSERVICE_FUNCTION);
                tableDownload.setWebserviceFunction(value);
                value = XMLPaserUtil.getAttrValue(node,
                        MasterConfigParser.IS_HAVE_PHOTO);
                if ((value != null) && value.equalsIgnoreCase("Y")) {
                    tableDownload.setHavePhoto(true);
                }

                value = XMLPaserUtil.getAttrValue(node,
                        MasterConfigParser.IS_DOWNLOAD_ONLY);
                if (!TextUtils.isEmpty(value)) {
                    if (value.equalsIgnoreCase("Y")) {
                        tableDownload.setDownloadOnly(true);
                    }
                }

                value = XMLPaserUtil.getAttrValue(node,
                        MasterConfigParser.IS_CLEAR_ALL);
                if (!TextUtils.isEmpty(value)) {
                    if (value.equalsIgnoreCase("Y")) {
                        tableDownload.setClearAll(true);
                    }
                }
            }
            tableDownloads.put(tableDownload.getTableName(), tableDownload);
        }
        return tableDownloads;
    }

    private static GenericDictionary<String, TableInit> parseTableInit(
            final NodeList nodeList) {
        if (nodeList.getLength() == 0) {
            return new GenericDictionary<String, TableInit>();
        }
        final GenericDictionary<String, TableInit> tableInits = new GenericDictionary<String, TableInit>();
        for (int i = 0; i < nodeList.getLength(); i++) {
            final Node node = nodeList.item(i);
            final String value = XMLPaserUtil.getNodeValue(node);
            tableInits.put(value, new TableInit(value));
        }
        return tableInits;
    }
}
